import { JXDef } from "../../../conventions/JXCommon";
import { NewFillArray } from "../../../Core/FrameEx/ES5Ex";
import { GCtrl } from "../../../Core/GCtrl";
import GParam from "../../../Core/GEvent/GParam";
import { GLocal } from "../../../Core/Manager/DataPool";
import { BUFFINFO, CMsg, OFFICERITEM, VIPBOXTYPE, VIPRECEIVE } from "../../Common/Define";
import { L } from "../../Common/Language";
import TimeUtil from "../../Common/TimeUtils";
import { JXLocales } from "../../Common/Zh";
import GameMgr from "../../Logic/GameMgr";
import { INVALID_VALUE, INVALID_VALUE_ZERO, OBJECT_COPY, PRIORITY_DATA } from './../../../Core/CoreDefine';

const { ccclass } = cc._decorator;
@ccclass
export class LUserData extends GLocal {
    public $localKey = 'LUserData';
    //第一次登陆游戏时间
    private $fristTime: number = 0;
    /**免费强征次数 */
    private $freePress: number;
    /**使用每日免费强征次数的时间 */
    private $freePressDate: number = 0;
    /**英雄buff */
    private $heroBuff = [];
    /**用户buff */
    private $userBuff: number[] = NewFillArray(6, INVALID_VALUE_ZERO);
    /**章节宝箱领取 */
    private $chapterBoxArr: Array<number> = [];
    /**官爵宝箱领取 */
    private $officerBoxReceiverArr: Array<OfficeBox> = [];
    /**vip宝箱领取 */
    private $vipReward: Array<vipReward> = [];
    /**竞技场 */
    private $sportsLv: number;
    /**签到官爵 */
    private $signOfficerLv: number;
    /**官爵等级 */
    private $officerLv: number;
    /**当前vip等级 */
    private $vipLv: number;
    /**广告累计观看次数 */
    private $adWatchTime: number;
    /**当前关卡 */
    private $level: number;
    private $levelStart: number[];
    private $HeroInBattle: number[] = NewFillArray(5, INVALID_VALUE);
    /**章节地图宝箱奖励领取 */
    private $mainSectionReward: SStoryDataRaw[][] = [];
    /**签到的时间 */
    private $signInDate: number = 0;
    /**使用每日免费获取装备次数 */
    private $free: number;
    /**使用每日免费获取装备次数的时间 */
    private $useDayFreeDate: number = 0;
    /**连续签到时间 */
    private $signInCount: number = 0;
    /**双倍签到时间 */
    private $signDoubleDate: number = 0;
    /**开启每日礼包时间 */
    private $dayReceiveDate: Array<number> = [];
    /**在线时长 */
    private $onLine: number = 0;
    /**在线时间 */
    private $onLineDatTime: number = 0;
    /**在线奖励领取次数 */
    private $onLineNum: number = 0;
    /**在线时间可领取奖励倒计时间索引 */
    private $onLineAdd: number = 1;
    /**招募次数 */
    private $recruitCtrl: number = 0;
    /**招募累计奖励id */
    private $addDial: number = 1;
    /**领取招募奖励id */
    private $receiveId: number = 1;
    /**重樓獎勵*/
    private $towerReward: Array<number> = null;
    private $lastTowerGet: number = null;
    private $towerRewardSpeed: Array<number> = null;
    private $lastHideTime: number = null;
    private $time: number = null;
    private $guide: number[] = null;
    GameMgr: any;

    onInit() {
        this.load();
        this.$time = 0;
        this.initEvent();

        if (this.$vipReward.length < 1) {
            let vipReceiverArr = [];
            for (let i = 0; i < 5; i++) {
                let obj: vipReward = {
                    recycle: VIPRECEIVE.No,
                    recycleUp: VIPRECEIVE.No,
                }
                vipReceiverArr.push(obj);
            }
            this.vipReward = vipReceiverArr;
        }

        if (!this.$fristTime) {
            this.$fristTime = GCtrl.now;
        }
        if (!this.$freePress) {
            this.$freePress = 0;
        }

        if (!this.$lastTowerGet) {
            this.$lastTowerGet = GCtrl.now;
        }
        if (!this.$free) {
            this.$free = 0;
        }
        if (!this.$officerLv) {
            this.$officerLv = 0;
        }

        if (!this.$signOfficerLv) {
            this.$signOfficerLv = 0;
        }

        if (!this.$vipLv) {
            this.$vipLv = 0;
        }

        if (!this.$guide) { this.$guide = [] }
        if (!this.$adWatchTime) {
            this.$adWatchTime = 0;
        }

        if (!this.$sportsLv) {
            this.$sportsLv = 0;
        }

        if (!this.$level) {
            this.$level = 0;
        }
        if (!this.$levelStart) {
            this.$levelStart = [];
        }
        if (!this.$towerReward) {
            this.$towerReward = [0, 0];
        }
        if (!this.$towerRewardSpeed) {
            this.$towerRewardSpeed = [0, 0]
        }
        this.set();
    }

    /**注冊事件*/
    protected initEvent() {
        cc.game.on(cc.game.EVENT_SHOW, () => {
            let now = GCtrl.now;
            if ((now - this.$lastHideTime) > JXDef.Time.MINUTE) {
                let time = now - this.$lastHideTime;
                let surplus = Math.floor(time / JXDef.Time.MINUTE);
                this.$towerReward[0] = this.$towerReward[0] + this.$towerRewardSpeed[0] * surplus;
                this.$towerReward[1] = this.$towerReward[1] + this.$towerRewardSpeed[1] * surplus;
                GCtrl.ES.emit(CMsg.client.tower.onAddTowerReward)
            }
        })
        cc.game.on(cc.game.EVENT_HIDE, () => {
            this.$lastHideTime = GCtrl.now;
            this.set();
        })
        GCtrl.ES.on(GCtrl.GTimerSecondEventMsg, this, this.addTowerReward.bind(this), PRIORITY_DATA);
    }

    /**是否是新用户 (当天是否是用户注册当天)*/
    public checkIsNewUser() {
        return TimeUtil.isSameDay(GCtrl.now, this.$fristTime)
    }
    public addTowerSpeed(arr: number[]) {
        if (!this.$towerRewardSpeed[0] && !this.$towerRewardSpeed[1]) {
            this.lastTowerGet = GCtrl.now
        }
        this.$towerRewardSpeed[0] += arr[0];
        this.$towerRewardSpeed[1] += arr[1];
        this.set();
    }

    public getTowerSpeed() {
        return OBJECT_COPY(this.$towerRewardSpeed);
    }

    public getRewardInfo() {
        return OBJECT_COPY(this.$towerReward);
    }

    protected addTowerReward() {
        this.$time++;
        if (this.$time >= 60) {
            this.$towerReward[0] += this.$towerRewardSpeed[0];
            this.$towerReward[1] += this.$towerRewardSpeed[1];
            this.$time = 0;
            GCtrl.ES.emit(CMsg.client.tower.onAddTowerReward)
            this.set();
        }
    }

    public getTowerReward() {
        this.$time = 0;
        this.$towerReward = [0, 0];
        this.$lastTowerGet = GCtrl.now;
        this.set();
    }

    public getLastTowerId() {
        return this.$sportsLv;
    }

    /**获取用户指定增益加成 */
    public getUserBuff(buffInfo: BUFFINFO): number {
        return this.$userBuff[buffInfo]
    }



    /**用户增益增加 */
    protected changeBuff(arr: number[]) {
        arr.forEach((v, index) => {
            if (v == 0) {
                return;
            }
            this.$userBuff[index] += v;
            this.$userBuff[index] = Number(this.$userBuff[index].toFixed(4))
        })
        this.set();
    }

    /**英雄增益 */
    protected changeHeroBuff(arr: number[][]) {
        arr.forEach((v: number[]) => {
            if (v.length > 0) {
                this.$heroBuff.push(v);
            }
        })
    }

    /**指定英雄buff增益 */
    public getHeroBuff(heroId: number): Array<Array<number>> {
        let arr = [];
        this.$heroBuff.forEach((v: number[]) => {
            v.forEach((h) => {
                if (h == heroId) {
                    arr.push(v);
                }
            });
        })
        return arr
    }


    public set sportsLv(v: number) {
        this.$sportsLv = v;
        this.set();
    }

    public get freePress() {
        return this.$freePress;
    }

    public set freePress(v) {
        this.$freePress = v;
        this.set();
    }


    public get addDial() {
        return this.$addDial;
    }

    public set addDial(v) {
        this.$addDial++;
        this.set();
    }

    public get recruitCtrl() {
        return this.$recruitCtrl
    }

    public set recruitCtrl(v) {
        this.$recruitCtrl += v;
        this.set();
    }

    public get receiveId() {
        return this.$receiveId;
    }

    public set receiveId(v) {
        this.$receiveId++;
        this.set();
    }

    public get free() {
        return this.$free;
    }

    public set free(v) {
        this.$free = v;
        this.set();
    }

    public getStarByLevel(lv: number) {
        let num = this.$levelStart[lv];
        if (!num) return 0;
        return num
    }

    public setStarByLevel(lv: number, star: number) {
        if (this.$levelStart[lv]) {
            this.$levelStart[lv] = this.$levelStart[lv] < star ? star : this.$levelStart[lv];
        } else {
            this.$levelStart[lv] = star;
        }

        this.set();
    }


    public get lastTowerGet() {
        return this.$lastTowerGet
    }

    public set lastTowerGet(v) {
        this.$lastTowerGet = v;
    }


    public get vipReward() {
        return this.$vipReward;
    }

    public set vipReward(v) {
        this.$vipReward = v;
        this.set();
    }

    /**获取宝箱状态类型 */
    public getVipReward(id: number, flag: VIPBOXTYPE): VIPRECEIVE {
        let type = VIPRECEIVE.No;
        if (flag == VIPBOXTYPE.DAYBOX) {
            type = this.$vipReward[id].recycle;
        } else {
            type = this.$vipReward[id].recycleUp;
        }
        return type
    }

    /**设置宝箱状态类型 */
    public setVipReward(id: number, flag: VIPBOXTYPE, type: VIPRECEIVE) {
        if (flag == VIPBOXTYPE.DAYBOX) {
            this.$vipReward[id].recycle = type;
        } else {
            this.$vipReward[id].recycleUp = type;
        }
        this.set();
    }

    public get dayReceiveDate() {
        return this.$dayReceiveDate;
    }

    public set dayReceiveDate(v) {
        this.$dayReceiveDate = v;
        this.set();
    }

    public getOfficeStatus(id: number) {
        if (!this.$officerBoxReceiverArr[id]) {
            this.$officerBoxReceiverArr[id] = {
                adBox: OFFICERITEM.NOT,
                box: OFFICERITEM.NOT
            }
            this.set();
        }
        return this.$officerBoxReceiverArr[id];
    }

    public setOfficeStatus(id: number, statu: OfficeBox) {
        this.$officerBoxReceiverArr[id] = statu;
        this.set();
    }

    public get chapterBoxArr() {
        return this.$chapterBoxArr;
    }

    public set chapterBoxArr(v) {
        this.$chapterBoxArr = v;
        this.set();
    }

    public get mainSectionReward() {
        return this.$mainSectionReward;
    }

    public set mainSectionReward(arr) {
        this.$mainSectionReward = arr;
        this.set();
    }

    public get level() {
        return this.$level;
    }

    public set level(v) {
        if (v > this.$level) {
            this.$level = v;
            this.set();
            GCtrl.ES.emit(CMsg.client.home.onaddLevel);
        }
    }

    public get heroInBattle() {
        return this.$HeroInBattle;
    }

    public set heroInBattle(v) {
        this.$HeroInBattle = v;
        this.set();
    }

    public get adWatchTime() {
        return this.$adWatchTime;
    }

    public get officerLv() {
        return this.$officerLv;
    }

    public set officerLv(v) {
        this.$officerLv = v;
        this.set();
    }


    public get signOfficerLv() {
        return this.$signOfficerLv;
    }

    public set signOfficerLv(v) {
        this.$signOfficerLv = v;
        this.set();
    }

    public get vipLv() {
        return this.$vipLv;
    }

    public addAdWatchTime(time: number = 1) {
        this.$adWatchTime += time;
        let nextVip = this.$vipLv + 1;
        GCtrl.ES.emit(CMsg.client.home.onVipLvUp, new GParam(this.$vipLv));
        if (nextVip > GameMgr.vipData.size) {
            nextVip = this.$vipLv;
            this.set();
            return;
        }
        let vipRaw = GameMgr.vipData.getRaw<SVipDataRaw>(nextVip)
        if (nextVip && vipRaw.next <= this.$adWatchTime) {
            this.$vipLv++
            this.changeBuff(vipRaw.buff);
            this.changeHeroBuff(vipRaw.buff2);
        }

        this.set();
    }



    public addSectionReward() {

    }

    /*签到开始 */
    public signIn() {
        this.$signInDate = GCtrl.now;
        GCtrl.ES.emit(CMsg.client.home.onSign);
        this.$signInCount++;
        this.set();
        return this.$signInCount;
    }

    getOnLine() {
        return this.$onLine;
    }

    /**在线时长 */
    public setOnLine(v) {
        if (this.onLineDayDate()) {
            this.$onLine = v;
        } else {
            this.$onLine = 0;
            this.$onLineNum = 0;
            this.$onLineAdd = 1;
        }
        this.set();
    }

    /**设置倒计时自增索引值 */
    public setOnLineAdd() {
        this.$onLineAdd++;
        this.set();
    }

    public get onLineAddNum(): number {
        return this.$onLineAdd;
    }

    /**在线奖励领取 */
    public setOnLineRewardNum() {
        this.$onLineNum++;
        GameMgr.sdkMgr.umaSetPoint(JXDef.umaPoint.timeBox, { msg: L(JXLocales.tower.onlineRwWard, this.$onLineNum) })
        this.set();
    }

    /**获取在线奖励领取数量 */
    public getOnLineRewardNum() {
        return this.$onLineNum;
    }

    /**是否同天在线 */
    public onLineDayDate(): boolean {
        return TimeUtil.isSameDay(this.$onLineDatTime, GCtrl.now) ? true : false;
    }

    public onLineTime() {
        this.$onLineDatTime = GCtrl.now;
        this.set();
    }

    /**签到双倍领取时间 */
    public signDouble() {
        this.$signDoubleDate = GCtrl.now;
        this.set();
    }

    /**当天是否有双倍领取 */
    public doubleSign(): boolean {
        return TimeUtil.isSameDay(this.$signDoubleDate, GCtrl.now) ? true : false;
    }


    public setSignCount(v) {
        this.$signInCount = v;
    }

    public getSignCount() {
        return this.$signInCount;
    }
    public todayIsSignIn(): boolean {
        return TimeUtil.isSameDay(this.$signInDate, GCtrl.now) ? true : false;
    }

    /**使用免费购买装备 */
    public useDayFree() {
        this.$useDayFreeDate = GCtrl.now;
        this.$free++;
        this.set();
    }

    /**使用免费强征 */
    public useFreePress() {
        this.$freePressDate = GCtrl.now;
        this.$freePress++;
        this.set();
    }

    /**是否同天使用免费强征 */
    public todayIsUseFreePressDate(): boolean {
        return TimeUtil.isSameDay(this.$freePressDate, GCtrl.now) ? true : false;
    }

    /**是否同天使用免费获取装备 */
    public todayIsUseDayFreeDate(): boolean {
        return TimeUtil.isSameDay(this.$useDayFreeDate, GCtrl.now) ? true : false;
    }

    /**vip当天是否可以开启每日宝箱 */
    public todayIsDayReceiveDate(index: number) {
        return TimeUtil.isSameDay(this.$dayReceiveDate[index], GCtrl.now) ? true : false;
    }
    public useDayReceiveDate(index: number) {
        this.$dayReceiveDate[index] = GCtrl.now;
        this.set();
    }

    public getSignTodayIndex(): number {
        let index = this.$signInCount;
        if (this.todayIsSignIn()) {
            index;
        }
        return index;
    }

    public isGuidseExits(guideId: number) {
        let raw = GameMgr.guideChainData.getRaw(guideId);
        if (raw) {
            let guide = this.$guide;
            return guide.indexOf(guideId) != INVALID_VALUE;
        } else {
            return true;
        }
    }

    public setGuides(guideId: number) {
        if (this.$guide.indexOf(guideId) == INVALID_VALUE) {
            this.$guide.push(guideId)
            this.set();
        }
    }

    public get guide() {
        return this.$guide;
    }

    public isDoneGuide() {
        return this.$guide.length >= GameMgr.guideChainData.data.size;
    }

    public checkGuideIsOver() {
        let arr = GameMgr.guideChainData.data.values<SGuideChainDataRaw>();
        for (let index = 0; index < arr.length; index++) {
            let raw = arr[index];
            let isExit = this.isGuidseExits(raw.guideId);
            if (!isExit) {
                return false;
            }
        }

        return true;
    }

    public heroNames(id) {
        var str: string = null;
        switch (id) {
            case 1001:
                {
                    str = "枪兵"
                    break;
                }
            case 1002:
                {
                    str = "关羽"
                    break;
                }
            case 1003:
                {
                    str = "诸葛亮"
                    break;
                }
            case 1004:
                {
                    str = "花木兰"
                    break;
                }
            case 1005:
                {
                    str = "孟获"
                    break;
                }
            case 1006:
                {
                    str = "黄忠"
                    break;
                }
            case 1007:
                {
                    str = "布"
                    break;
                }

            default:
                break;
        }
        return str
    }


    /**
     * hero
     */
    public heroType(id) {
        var str: string = null;
        switch (id) {
            case 1:
                {
                    str = "兵"
                    break;
                }
            case 2:
                {
                    str = "车"
                    break;
                }
            case 3:
                {
                    str = "马"
                    break;
                }
            case 4:
                {
                    str = "炮"
                    break;
                }
            case 5:
                {
                    str = "象"
                    break;
                }
            case 6:
                {
                    str = "士"
                    break;
                }


            default:
                break;
        }
        return str
    }

    public herotarit(id) {
        var str: string = null;
        switch (id) {
            case 1:
                {
                    str = "白色"
                    break;
                }
            case 2:
                {
                    str = "绿色"
                    break;
                }
            case 3:
                {
                    str = "蓝色"
                    break;
                }
            case 4:
                {
                    str = "紫色"
                    break;
                }
            case 5:
                {
                    str = "金色"
                    break;
                }
            case 6:
                {
                    str = "红色"
                    break;
                }


            default:
                break;
        }
        return str
    }

    public heroOfficer(id) {
        var str: string = null;
        switch (id) {
            case 1:
                {
                    str = "主簿"
                    break;
                }
            case 2:
                {
                    str = "县丞"
                    break;
                }
            case 3:
                {
                    str = "都事"
                    break;
                }
            case 4:
                {
                    str = "知县"
                    break;
                }
            case 5:
                {
                    str = "知州"
                    break;
                }
            case 6:
                {
                    str = "知府"
                    break;
                }
            case 7:
                {
                    str = "尚书"
                    break;
                }
            case 8:
                {
                    str = "延尉"
                    break;
                }
            case 9:
                {
                    str = "太尉"
                    break;
                }
            case 10:
                {
                    str = "太史"
                    break;
                }
            case 11:
                {
                    str = "太守"
                    break;
                }
            default:
                break;
        }
        return str
    }

}